﻿using System;
using System.Linq;
using System.Collections.Generic;

namespace DataAccess.Repository
{
	public class KPIRepository : IDisposable, IKPIRepository
	{
		private KPIDbContext _KPIDbContext = new KPIDbContext();

		private Models.KPI GetKPIFromReader(System.Data.Common.DbDataReader rd)
		{
			Models.KPI result = null;

			if(rd != null)
			{
				var item = new Models.KPI();
				for(var i = 0; i < rd.FieldCount; i++)
				{
					switch(rd.GetName(i))
					{
						case "KPIID":
							{
								item.KPIID = Convert.ToInt32(rd[rd.GetName(i)]);
							}
							break;
						case "GroupID":
							{
								item.GroupID = Convert.ToInt32(rd[rd.GetName(i)]);
							}
							break;
						case "TheYear":
							{
								item.TheYear = rd[rd.GetName(i)] == DBNull.Value ? 0 : Convert.ToInt32(rd[rd.GetName(i)]);
							}
							break;
						case "KPIContent":
							{
								item.KPIContent = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
							}
							break;
						case "KPIAddTime":
							{
								if(rd[rd.GetName(i)] != DBNull.Value)
								{
									item.KPIAddTime = Convert.ToDateTime(rd[rd.GetName(i)]);
								}
							}
							break;
						case "KPIModifyTime":
							{
								if(rd[rd.GetName(i)] != DBNull.Value)
								{
									item.KPIModifyTime = Convert.ToDateTime(rd[rd.GetName(i)]);
								}
							}
							break;
						case "StartTime":
							{
								if(rd[rd.GetName(i)] != DBNull.Value)
								{
									item.StartTime = Convert.ToDateTime(rd[rd.GetName(i)]);
								}
							}
							break;
						case "FinishTime":
							{
								if(rd[rd.GetName(i)] != DBNull.Value)
								{
									item.FinishTime = Convert.ToDateTime(rd[rd.GetName(i)]);
								}
							}
							break;
						case "ResponseDepartment":
							{
								item.ResponseDepartment = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
							}
							break;
						case "ResponsablePerson":
							{
								item.ResponsablePerson = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
							}
							break;
						case "RPTel":
							{
								item.RPTel = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
							}
							break;
						case "ResponsibleLeadership":
							{
								item.ResponsibleLeadership = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
							}
							break;
						case "RLTel":
							{
								item.RLTel = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
							}
							break;
						case "ActionPlans":
							{
								item.ActionPlans = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
							}
							break;
						case "CurrentState":
							{
								item.CurrentState = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
							}
							break;
						case "PreState":
							{
								item.PreState = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
							}
							break;
						case "CreateUserName":
							{
								item.CreateUserName = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
							}
							break;
						case "GroupName":
							{
								if(item.TheGroup == null)
								{
									item.TheGroup = new Models.Group();
								}

								item.TheGroup.GroupID = Convert.ToInt32(rd["GroupID"]);
								item.TheGroup.GroupName = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
							}
							break;
					}
				}

				result = item;
			}

			return result;
		}

		#region IDisposable Members

		public void Dispose()
		{
			if(_KPIDbContext != null)
			{
				_KPIDbContext.Dispose();
			}
		}

		#endregion

		#region IKPIRepository Members

		/// <summary>
		/// 添加KPI
		/// </summary>
		/// <param name="kpi">要添加的KPI对象</param>
		/// <returns></returns>
		public bool CreateKPI(Models.KPI kpi)
		{
			var result = false;

			if(kpi != null)
			{
				try
				{
					_KPIDbContext.KPI.Add(kpi);

					if(_KPIDbContext.SaveChanges() > 0)
					{
						result = true;
					}
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		/// <summary>
		/// 更新KPI
		/// </summary>
		/// <param name="kpi">要更新的KPI</param>
		/// <param name="updateFromKPIForUpdate">是否从表KPIForUpdate更新</param>
		/// <returns>true/false</returns>
		public bool UpdateKPI(Models.KPI kpi, bool updateFromKPIForUpdate)
		{
			var result = false;

			if(kpi != null && kpi.KPIID > 0)
			{
				try
				{
					var orgKPI = _KPIDbContext.KPI.Find(kpi.KPIID);

					if(orgKPI != null)
					{
						kpi.KPIModifyTime = DateTime.Now;
						kpi.KPIAddTime = orgKPI.KPIAddTime;

						_KPIDbContext.Entry(orgKPI).CurrentValues.SetValues(kpi);

						if(updateFromKPIForUpdate)
						{
							if(kpi.CurrentState == DataAccess.Models.KPIStates.KPI_Of_Modification_Modified_Review_Approved)
							{
								if(orgKPI.TheKPIForUpdate != null)
								{
									orgKPI.ActionPlans = orgKPI.TheKPIForUpdate.UpdatedActionPlan;
									orgKPI.FinishTime = orgKPI.TheKPIForUpdate.UpdatedFinishTime;
									orgKPI.KPIContent = orgKPI.TheKPIForUpdate.UpdatedKPIContent;
									orgKPI.ResponsablePerson = orgKPI.TheKPIForUpdate.UpdatedResponsablePerson;
									orgKPI.ResponseDepartment = orgKPI.TheKPIForUpdate.UpdatedResponseDepartment;
									orgKPI.ResponsibleLeadership = orgKPI.TheKPIForUpdate.UpdatedResponsibleLeadership;
									orgKPI.RLTel = orgKPI.TheKPIForUpdate.UpdatedRLTel;
									orgKPI.RPTel = orgKPI.TheKPIForUpdate.UpdatedRPTel;
									orgKPI.StartTime = orgKPI.TheKPIForUpdate.UpdatedStartTime;
								}
							}

							var theKPIForUpdate = _KPIDbContext.KPIForUpdate.Find(kpi.KPIID);

							if(theKPIForUpdate != null)
							{
								_KPIDbContext.KPIForUpdate.Remove(theKPIForUpdate);
							}
						}

						if(_KPIDbContext.SaveChanges() > 0)
						{
							result = true;
						}
					}
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		/// <summary>
		/// 删除KPI
		/// </summary>
		/// <param name="id">KPIID</param>
		/// <param name="completeDelete">是否彻底删除</param>
		/// <returns></returns>
		public bool DeleteKPI(int id, bool completeDelete)
		{
			var result = false;

			if(id > 0)
			{
				try
				{
					var kpi = _KPIDbContext.KPI.Find(id);

					if(kpi != null)
					{
						if(completeDelete)
						{
							_KPIDbContext.KPI.Remove(kpi);
						}
						else
						{
							kpi.KPIModifyTime = DateTime.Now;
							kpi.CurrentState = Models.KPIStates.Delete;
						}

						result = (_KPIDbContext.SaveChanges() > 0);
					}
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		/// <summary>
		/// 取KPI
		/// </summary>
		/// <param name="groupID">单位ID</param>
		/// <param name="state">状态(为空时所有状态)</param>
		/// <param name="y">年份</param>
		/// <param name="pageIndex">当前页</param>
		/// <param name="pageSize">每页记录数</param>
		/// <param name="totalRecords">总记录数</param>
		/// <returns>KPI列表</returns>
		public List<Models.KPI> GetKPIs(int groupID, string state, int y, int pageIndex, int pageSize, out int totalRecords)
		{
			List<Models.KPI> result = null;
			totalRecords = 0;

			System.Data.Common.DbDataReader rd = null;

			if(groupID > 0)
			{
				try
				{
					_KPIDbContext.Database.Initialize(false);

					var cmd = _KPIDbContext.Database.Connection.CreateCommand();
					cmd.CommandText = "KPI_GetKPIs";
					cmd.CommandType = System.Data.CommandType.StoredProcedure;

					System.Data.Common.DbParameter p1 = cmd.CreateParameter();
					p1.DbType = System.Data.DbType.Int32;
					p1.Direction = System.Data.ParameterDirection.Input;
					p1.ParameterName = "@GROUPID";
					p1.Value = groupID;
					System.Data.Common.DbParameter p2 = cmd.CreateParameter();
					p2.DbType = System.Data.DbType.String;
					p2.Direction = System.Data.ParameterDirection.Input;
					p2.ParameterName = "@STATE";
					p2.Value = state;
					System.Data.Common.DbParameter p3 = cmd.CreateParameter();
					p3.DbType = System.Data.DbType.Int32;
					p3.Direction = System.Data.ParameterDirection.Input;
					p3.ParameterName = "@THEYEAR";
					p3.Value = y;
					System.Data.Common.DbParameter p4 = cmd.CreateParameter();
					p4.DbType = System.Data.DbType.Int32;
					p4.Direction = System.Data.ParameterDirection.Input;
					p4.ParameterName = "@PAGEINDEX";
					p4.Value = pageIndex;
					System.Data.Common.DbParameter p5 = cmd.CreateParameter();
					p5.DbType = System.Data.DbType.Int32;
					p5.Direction = System.Data.ParameterDirection.Input;
					p5.ParameterName = "@PAGESIZE";
					p5.Value = pageSize;
					System.Data.Common.DbParameter p6 = cmd.CreateParameter();
					p6.DbType = System.Data.DbType.Int32;
					p6.Direction = System.Data.ParameterDirection.InputOutput;
					p6.ParameterName = "@TOTALRECORDS";
					p6.Value = totalRecords;

					cmd.Parameters.Add(p1);
					cmd.Parameters.Add(p2);
					cmd.Parameters.Add(p3);
					cmd.Parameters.Add(p4);
					cmd.Parameters.Add(p5);
					cmd.Parameters.Add(p6);

					if(_KPIDbContext.Database.Connection.State != System.Data.ConnectionState.Open)
					{
						_KPIDbContext.Database.Connection.Open();
					}

					rd = cmd.ExecuteReader();

					while(rd.Read())
					{
						var item = GetKPIFromReader(rd);

						if(item != null)
						{
							if(result == null)
							{
								result = new List<Models.KPI>();
							}

							result.Add(item);
						}
					}

					if(!rd.IsClosed)
					{
						rd.Close();
					}

					totalRecords = Convert.ToInt32(cmd.Parameters["@TOTALRECORDS"].Value);
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		/// <summary>
		/// 取指定ID的KPI
		/// </summary>
		/// <param name="id">KPIID</param>
		/// <returns></returns>
		public Models.KPI GetTheKPI(int id)
		{
			Models.KPI result = null;

			if(id > 0)
			{
				try
				{
					result = _KPIDbContext.KPI.Include("TheGroup").Include("TheKPIForUpdate").Include("TheKPIProgress").Include("TheKPIProgressForUpdate").FirstOrDefault(kpi => kpi.KPIID == id);
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		/// <summary>
		/// 添加KPIForUpdate
		/// </summary>
		/// <param name="theKPIForUpdate"></param>
		/// <returns></returns>
		public bool CreateKPIForUpdate(Models.KPIForUpdate theKPIForUpdate)
		{
			var result = false;

			if(theKPIForUpdate != null)
			{
				try
				{
					var orgKPIForUpdate = _KPIDbContext.KPIForUpdate.Find(theKPIForUpdate.KPIID);

					if(orgKPIForUpdate == null)
					{
						_KPIDbContext.KPIForUpdate.Add(theKPIForUpdate);
					}
					else
					{
						_KPIDbContext.Entry(orgKPIForUpdate).CurrentValues.SetValues(theKPIForUpdate);
					}

					result = _KPIDbContext.SaveChanges() > 0;
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		#endregion
	}
}
